package com.h117121.fashionshop.core.dom;

import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@SuppressWarnings("serial")
@Entity
@Table(name = "Invoice")
public class Invoice extends BaseDom {
	@Enumerated(EnumType.STRING)
	@Column(name = "State")
	private InvoiceState state;

	@Enumerated(EnumType.STRING)
	@Column(name = "PaymentMethod")
	private PaymentMethod paymentMethod;

	@Column(name = "DateCreated", nullable = false)
	private Date dateCreated;

	@Column(name = "DatePaid", nullable = true)
	private Date datePaid;

	@Column(name = "Description", length = 1000, nullable = true)
	private String description;

	@ManyToMany(fetch = FetchType.LAZY, targetEntity = ProductInInvoice.class, cascade = CascadeType.ALL)
	private List<ProductInInvoice> products;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "Account")
	private Account account;

	@Column(name = "Total", nullable = false)
	private long total;

	public enum InvoiceState {
		WAITING, PAID, CANCELED
	}

	public enum PaymentMethod {
		HOME, ONLINE
	}

	/**
	 * @return the state
	 */
	public InvoiceState getState() {
		return state;
	}

	/**
	 * @param state
	 *            the state to set
	 */
	public void setState(InvoiceState state) {
		this.state = state;
	}

	/**
	 * @return the paymentMethod
	 */
	public PaymentMethod getPaymentMethod() {
		return paymentMethod;
	}

	/**
	 * @param paymentMethod
	 *            the paymentMethod to set
	 */
	public void setPaymentMethod(PaymentMethod paymentMethod) {
		this.paymentMethod = paymentMethod;
	}

	/**
	 * @return the dateCreated
	 */
	public Date getDateCreated() {
		return dateCreated;
	}

	/**
	 * @param dateCreated
	 *            the dateCreated to set
	 */
	public void setDateCreated(Date dateCreated) {
		this.dateCreated = dateCreated;
	}

	/**
	 * @return the datePaid
	 */
	public Date getDatePaid() {
		return datePaid;
	}

	/**
	 * @param datePaid
	 *            the datePaid to set
	 */
	public void setDatePaid(Date datePaid) {
		this.datePaid = datePaid;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @param description
	 *            the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * @return the products
	 */
	public List<ProductInInvoice> getProducts() {
		return products;
	}

	/**
	 * @param products
	 *            the products to set
	 */
	public void setProducts(List<ProductInInvoice> products) {
		this.products = products;
		getTotal();
	}

	@Override
	public String toString() {
		return "*** " + id /* + " - " + this.account.getUserName() */+ " - "
				+ this.getPaymentMethod() /*
										 * + " - " + this.getProducts().size() +
										 * " items"
										 */+ " - " + this.getState() + " ***";
	}

	/**
	 * @return the account
	 */
	public Account getAccount() {
		return account;
	}

	/**
	 * @param account
	 *            the account to set
	 */
	public void setAccount(Account account) {
		this.account = account;
	}

	public long getTotal() {
		long sum = 0;
		for (ProductInInvoice item : products) {
			sum += item.getPrice() * item.getQuantity();
		}
		setTotal(sum);
		return sum;
	}

	public void setTotal(long total) {
		this.total = total;
	}
}